package com.fch.buffetorder.util;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.SetBucketPolicyArgs;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import java.io.IOException;
import java.io.InputStream;

@Component
public class MinioUtil {
    @Value("${minio.accessKey}")
    private String ACCESS_KEY;
    @Value("${minio.secretKey}")
    private String SECRET_KEY;
    @Value("${minio.endPoint}")
    private String END_POINT;
    @Value("${minio.defaultBucketName}")
    private String DEFAULT_BUCKET_NAME;
    private MinioClient client;
    private void initClient() {
        client = MinioClient.builder().endpoint(END_POINT).credentials(ACCESS_KEY, SECRET_KEY).build();
    }

    public String storageFileWithReturnUrl(String genFileKey, MultipartFile file) {
        storageFile(DEFAULT_BUCKET_NAME, genFileKey, file);
        setFileAcl(DEFAULT_BUCKET_NAME, genFileKey);
        return getFileAuthUrl(DEFAULT_BUCKET_NAME, genFileKey);
    }

    private String getFileAuthUrl(String bucketName, String key) {
        try {
            initClient();
            return END_POINT + StrUtil.SLASH + bucketName + StrUtil.SLASH + key;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Minio获得图片地址失败");
        }
    }
    private void setFileAcl(String bucketName, String key) {
        try {
            JSONObject configObject = JSONUtil.createObj().set("Version", "2012-10-17");
            JSONArray statementArray = JSONUtil.createArray();
            JSONArray actionArray = JSONUtil.createArray();
            actionArray.put("s3:GetObject");
            JSONObject statementObject = JSONUtil.createObj();
            statementObject.set("Effect", "Allow").set("Principal", JSONUtil.createObj().set("AWS", JSONUtil.createArray().put("*")))
                    .set("Action", actionArray).set("Resource", JSONUtil.createArray().put("arn:aws:s3:::" + bucketName + "/*"));
            statementArray.put(statementObject);
            configObject.set("Statement", statementArray);
            String config = JSONUtil.toJsonStr(configObject);
            SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder().bucket(bucketName).config(config).build();
            client.setBucketPolicy(setBucketPolicyArgs);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Minio赋权失败");
        }
    }

    private void storageFile(String bucketName, String key, InputStream inputStream) throws IOException {
        try {
            initClient();
            PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(bucketName).object(key)
                    .contentType(getFileContentType(key)).stream(inputStream, inputStream.available(), -1).build();
            client.putObject(putObjectArgs);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Minio储存图片失败");
        } finally {
            IoUtil.close(inputStream);
        }
    }

    private static String getFileContentType(String key) {
        // 根据文件名获取contentType
        String contentType = "application/octet-stream";
        if (key.contains(".")) {
            contentType = MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(key);
        }
        return contentType;
    }

    private void storageFile(String bucketName, String key, MultipartFile multipartFile) {
        try (InputStream inputStream = multipartFile.getInputStream()) {
            storageFile(bucketName, key, inputStream);
        } catch (IOException e) {
            throw new RuntimeException("获取文件流异常，名称是：{}" + multipartFile.getName());
        }
    }
}
